package pers.litao.bit.user.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import pers.litao.bit.commons.dto.UserDTO;
import pers.litao.bit.commons.entities.user.AddressEntity;
import pers.litao.bit.commons.entities.user.UserInfoEntity;
import pers.litao.bit.commons.utils.*;
import pers.litao.bit.commons.vo.user.CheckVo;
import pers.litao.bit.commons.vo.user.UserRegisterVo;
import pers.litao.bit.user.openfeign.ThirdFeignService;
import pers.litao.bit.user.dao.UserSellerMapper;
import pers.litao.bit.user.service.AddressService;
import pers.litao.bit.user.service.UserInfoService;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 李涛
 * @date 2020-11-16 15:44
 */
@Service
@Slf4j
public class UserInfoServiceImpl extends ServiceImpl<UserSellerMapper, UserInfoEntity> implements UserInfoService {

    @Resource
    private AddressService addressService;

    @Resource
    private ThirdFeignService thirdFeignService;

    /**
     * 注册账号
     *
     * @param userRegisterVo 用户信息和地址实体类
     * @return
     */
    @Override
    @Transactional(rollbackFor=Exception.class)
    public R userSave(UserRegisterVo userRegisterVo) {
        UserInfoEntity userInfoEntity = new UserInfoEntity();
        AddressEntity address = new AddressEntity();
        CheckVo checkVo = new CheckVo();
        BeanUtils.copyProperties(userRegisterVo, userInfoEntity);
        BeanUtils.copyProperties(userRegisterVo, address);

        /*
            验证数据问题
         */
        List<UserInfoEntity> users = this.list(new QueryWrapper<UserInfoEntity>().eq("phone", userInfoEntity.getPhone()));
        if(users != null && users.size() > 0){  //当前用户已存在
            log.error("用户注册失败,"+userRegisterVo.getPhone()+"已存在" +SysUtil.getClientInfo().buildInfo());
            return R.error(Constant.ResponseCode.ERROR_USER_EXIST.getCode(),
                    Constant.ResponseCode.ERROR_USER_EXIST.getMsg(),null);
        }
        /*
         *  验证码校验
         */
        checkVo.setCode(userRegisterVo.getKeyWord());
        checkVo.setPhone(userRegisterVo.getPhone());
        R check = thirdFeignService.check(checkVo);
        // 验证码错误
        if(!(boolean)check.get("data")){
            log.error("用户注册失败,验证码校验错误" +SysUtil.getClientInfo().buildInfo());
            return R.error(Constant.ResponseCode.KEY_ERROR.getCode()
            ,Constant.ResponseCode.KEY_ERROR.getMsg(),null);
        }

        /*
        验证店铺
         */
        if(userInfoEntity.getIdentity() == 1 && StrUtil.isBlank(userInfoEntity.getStoreName())){ //销售商店铺名不存在
            log.error("供应商的店铺名不能为空" +SysUtil.getClientInfo().buildInfo());
            Map<String,Object> map = new HashMap<>();
            map.put("storeName","供应商的店铺名不能为空");
            return R.error(Constant.ResponseCode.SUBMIT_DATA_ILLEGALITY.getCode(),
                    Constant.ResponseCode.SUBMIT_DATA_ILLEGALITY.getMsg(),map);
        }
        else if(userInfoEntity.getIdentity() == 0) { //把零售商店铺名设为null
            userInfoEntity.setStoreName(null);
        }
        else {
            if(StrUtil.trim(userInfoEntity.getStoreName()).length() > 10){ //店铺名格式错误
                Map<String,Object> map = new HashMap<>();
                log.error("供应商的店铺名大于10个" +SysUtil.getClientInfo().buildInfo());
                map.put("storeName","供应商的店铺名大于10个");
                return R.error(Constant.ResponseCode.SUBMIT_DATA_ILLEGALITY.getCode(),
                        Constant.ResponseCode.SUBMIT_DATA_ILLEGALITY.getMsg(),map);
            }
            userInfoEntity.setStoreName(StrUtil.trim(userInfoEntity.getStoreName()));
        }
        /*
        保存用户
         */
        // 加密密码
        String newPwd = SHA256Utils.encryption(userInfoEntity.getPassword(), userInfoEntity.getPhone());
        // 设置密码
        userInfoEntity.setPassword(newPwd);
        // 保存用户
        this.save(userInfoEntity);
        //查找id
        List<UserInfoEntity> newUser = this.list(new QueryWrapper<UserInfoEntity>()
        .eq("phone", userInfoEntity.getPhone()));
        //设置用户id
        address.setUserId(newUser.get(0).getId());
        //设置地址
        addressService.save(address);
        log.info("用户"+userRegisterVo.getPhone()+"注册成功" +SysUtil.getClientInfo().buildInfo());
        return R.ok();
    }

    /**
     * 账号登录
     *
     * @param userEntity 用户实体类
     * @return
     */
    @Override
    public R userLogin(UserInfoEntity userEntity) {
        // 输入用户信息错误
        if(userEntity == null || userEntity.getPhone() == null || userEntity.getPassword() == null){ //未输入账号名或密码
            return R.error(Constant.ResponseCode.LOGIN_NOT_USER.getCode()
                    ,Constant.ResponseCode.LOGIN_NOT_USER.getMsg(),null);
        }
        String sha256Pwd = SHA256Utils.encryption(userEntity.getPassword(), userEntity.getPhone());
        UserInfoEntity oneUser = this.baseMapper.selectOne(new QueryWrapper<UserInfoEntity>()
                .eq("phone", userEntity.getPhone()));
        // 用户不存在
        if(oneUser == null){
            log.error("用户"+userEntity.getPhone()+"不存在" +SysUtil.getClientInfo().buildInfo());
            return R.error(Constant.ResponseCode.ERROR_USER_NOT_EXIST.getCode(),
                    Constant.ResponseCode.ERROR_USER_NOT_EXIST.getMsg(),null);
        }
        if(!StrUtil.equals(oneUser.getPassword(), sha256Pwd)){
            log.error("用户"+oneUser.getPhone()+"密码错误" +SysUtil.getClientInfo().buildInfo() );
            return R.error(Constant.ResponseCode.ERROR_USER_WRONG_PASSWORD.getCode(),
                    Constant.ResponseCode.ERROR_USER_WRONG_PASSWORD.getMsg(),null);
        }
        Map<String,Object> map = new HashMap<>();
        Map<String,Object> jwtArgs = new HashMap<>();
        jwtArgs.put("id", oneUser.getId());
        jwtArgs.put("phone", oneUser.getPhone());
        jwtArgs.put("identity",oneUser.getIdentity()); //身份，0表示零售商 1表示销售商
        String token = JwtUtil.createJWT(oneUser.getId() + "", jwtArgs, null);
        map.put("token",token);
        log.info("用户"+oneUser.getPhone()+"登陆成功" +SysUtil.getClientInfo().buildInfo() );
        return R.ok(map);
    }

    /**
     * 获取用户信息
     *
     * @param token
     * @return
     */
    @Override
    public R getUserInfo(String token,String service,Long id) {
        if(service == null){
            try {
                // 解析token
                Claims claims = JwtUtil.parseJWT(token);
                Long uId = claims.get("id", Long.class);
                UserInfoEntity userInfoEntity = this.baseMapper.selectById(uId);
                List<AddressEntity> userAddress = addressService.list(new QueryWrapper<AddressEntity>()
                        .eq("user_id", uId));
                userInfoEntity.setPassword(null);
                Map<String,Object> map = new HashMap<>();
                map.put("userData", userInfoEntity);
                map.put("addressData",userAddress.get(0));
                log.info("获取ID为"+uId+"的用户信息成功" +SysUtil.getClientInfo().buildInfo());
                return R.ok(map);
            } catch (Exception e) {
                log.error("获取用户信息失败",e);
                return  R.error(Constant.ResponseCode.TOKEM_INVALID.getCode(),
                        Constant.ResponseCode.TOKEM_INVALID.getMsg(),null);
            }
        }
        else{
            UserInfoEntity userInfoEntity = this.baseMapper.selectById(id);
            List<AddressEntity> userAddress = addressService.list(new QueryWrapper<AddressEntity>()
                    .eq("user_id", id));
            userInfoEntity.setPassword(null);
            Map<String,Object> map = new HashMap<>();
            map.put("userData", userInfoEntity);
            map.put("addressData",userAddress.get(0));
            log.info(service + "获取用户信息成功"+SysUtil.getClientInfo().buildInfo() );
            return R.ok(map);
        }
    }

    /**
     * 获取用户列表
     *
     * @param ids
     * @return
     */
    @Override
    public R getUserList(Long[] ids) {
        if(ids == null || ids.length == 0){
            return R.ok(new ArrayList<>());
        }
        List<UserDTO> userDTOS = this.baseMapper.selectBatch(ids);
        log.info("获取用户列表"+SysUtil.getClientInfo().buildInfo());
        return R.ok(userDTOS);
    }

    /**
     * 获取地址相同得到用户
     *
     * @param id
     * @return
     */
    @Override
    public R getUserIds(Long id) {
        AddressEntity addressEntity = addressService.list(new QueryWrapper<AddressEntity>().eq("user_id", id)).get(0);
        List<Long> userIDS = addressService.list(new QueryWrapper<AddressEntity>()
                .eq("city", addressEntity.getCity())).stream()
                .map(AddressEntity::getUserId)
                .collect(Collectors.toList());
        log.info("用户请求成功" + SysUtil.getClientInfo().buildInfo());
        return R.ok(userIDS);
    }

    /**
     * 更新用户密码
     *
     * @param userInfoEntity
     * @param loginUserInfo
     * @return
     */
    @Override
    public R updatePassword(UserRegisterVo userInfoEntity, LoginUserInfo loginUserInfo) {
        if(null == loginUserInfo){
            log.error("用户不存在" +SysUtil.getClientInfo().buildInfo());
            return R.error(Constant.ResponseCode.ILLEGAL_OPERATION.getCode(),
                    Constant.ResponseCode.ILLEGAL_OPERATION.getMsg(), null);
        }
        // 验证码校验
        CheckVo checkVo = new CheckVo();
        checkVo.setCode(userInfoEntity.getKeyWord());
        checkVo.setPhone(userInfoEntity.getPhone());
        R check = thirdFeignService.check(checkVo);
        // 验证码错误
        if(!(boolean)check.get("data")){
            log.error("用户注册失败,验证码校验错误" +SysUtil.getClientInfo().buildInfo());
            return R.error(Constant.ResponseCode.KEY_ERROR.getCode()
                    ,Constant.ResponseCode.KEY_ERROR.getMsg(),null);
        }
        // 加密密码
        String newPwd = SHA256Utils.encryption(userInfoEntity.getPassword(), userInfoEntity.getPhone());
        // 设置密码
        UserInfoEntity upUser = new UserInfoEntity();
        upUser.setId(loginUserInfo.getUserId());
        upUser.setPassword(newPwd);
        this.updateById(upUser);
        log.info("用户"+userInfoEntity.getPhone()+"更新密码成功" +SysUtil.getClientInfo().buildInfo());
        return R.ok();
    }


}
